home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XAAES_S.ZIP / XAAES / WIND_FNS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-06  |  26.1 KB  |  1,029 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <VDI.H>
  9. #include <MINTBIND.H>
  10. #include <OSBIND.H>
  11. #include <memory.h>
  12. #include "XA_DEFS.H"
  13. #include "XA_TYPES.H"
  14. #include "XA_GLOBL.H"
  15. #include "K_DEFS.H"
  16. #include "C_WINDOW.H"
  17. #include "EVENTS.H"
  18. #include "RECTLIST.H"
  19. #include "SCRLWIDG.H"
  20. #include "INFOWIDG.H"
  21. #include "TITLWIDG.H"
  22. #include "STD_WIDG.H"
  23. #include "graf_mou.h"
  24. #include "messages.h"
  25. #include "desktop.h"
  26. #include "RESOURCE.H"
  27. #include "SYSTEM.H"
  28. #include "OBJECTS.H"
  29.  
  30. /*
  31.     AES window handling functions
  32.     I've tried to support some of the AES4 extensions here as well as the plain
  33.     single tasking GEM ones.
  34. */
  35. unsigned long XA_wind_create(short clnt_pid, AESPB *pb)
  36. {
  37.     XA_WINDOW *new_window;
  38.     long tp=0;
  39.     
  40.     tp=pb->intin[0];
  41.     
  42.     new_window=create_window(clnt_pid, tp, pb->intin[1], pb->intin[2], pb->intin[3], pb->intin[4]);
  43.  
  44.     if (new_window)
  45.         pb->intout[0]=new_window->handle;    /* Return the window handle in intout[0] */
  46.     else
  47.         pb->intout[0]=-1;                    /* Fail to create window, return -ve number */
  48.  
  49.     return XAC_DONE;    /* Allow the kernal to wake up the client - we've done our bit */
  50. }
  51.  
  52. unsigned long XA_wind_open(short clnt_pid,AESPB *pb)
  53. {
  54.     XA_WINDOW *w,*wl;
  55.  
  56.     w=get_wind_by_handle(pb->intin[0]);    /* Get the window */
  57.  
  58.     if (w==NULL)
  59.     {
  60.         DIAGS(("WARNING:wind_open:Invalid window handle\n"));
  61.         pb->intout[0]=0;            /* Invalid window handle, return error */
  62.         return XAC_DONE;
  63.     }
  64.     
  65.     pb->intout[0]=1;                /* return ok in intout[0] */
  66.     
  67.     if (w->is_open==TRUE)            /* the window is already open, no need to do anything */
  68.     {
  69.         DIAGS(("WARNING: Attempt to open window when it was already open\n"));
  70.         return XAC_DONE;
  71.     }
  72.  
  73.     /* New top window - change the cursor to this clients choice */
  74.     graf_mouse(clients[clnt_pid].client_mouse, clients[clnt_pid].client_mouse_form);
  75.     
  76.     pull_wind_to_top(w);            /* Newly opened windows begin on top */
  77.  
  78.     wl=w->next;
  79. #if JOHAN_RECTANGLES
  80.     if (wl)        /* Refresh the previous top window as being 'non-topped' */
  81.     {
  82.         invalidate_rect_lists(wl);
  83.         display_non_topped_window(wl,NULL);
  84.  #if 0
  85.         send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, wl->x, wl->y, wl->w, wl->h);
  86.  #endif
  87.     }
  88. #else
  89.     if (wl)        /* Refresh the previous top window as being 'non-topped' */
  90.     {
  91.         display_non_topped_window(wl,NULL);
  92.         send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, wl->x, wl->y, wl->w, wl->h);
  93.     }
  94. #endif
  95.  
  96.     w->x=pb->intin[1];                /* Change the window coords */
  97.     w->y=pb->intin[2];
  98.     w->w=pb->intin[3];
  99.     w->h=pb->intin[4];
  100.  
  101.     w->is_open=TRUE;                /* Flag window as open */
  102.     w->window_status=XAWS_OPEN;
  103.  
  104.     calc_work_area(w);
  105.  
  106.     v_hide_c(V_handle);
  107.     display_non_topped_window(w,NULL);    /* Display the window (use the non-topped method as it sets clipping rectangles) */
  108.     send_app_message(clnt_pid, WM_REDRAW, 0, w->handle, w->x, w->y, w->w, w->h);
  109.     v_show_c(V_handle,1);
  110.  
  111.     return XAC_DONE;
  112. }
  113.  
  114. unsigned long XA_wind_close(short clnt_pid,AESPB *pb)
  115. {
  116.     XA_WINDOW *w;
  117.     
  118.     w=get_wind_by_handle(pb->intin[0]);    /* Get the window */
  119.  
  120.     if (w==NULL)
  121.     {
  122.         DIAGS(("WARNING:wind_close:Invalid window handle\n"));
  123.         pb->intout[0]=0;            /* Invalid window handle, return error */
  124.         return XAC_DONE;
  125.     }
  126.  
  127.     if (w->owner!=clnt_pid)        /* Clients can only close their own windows */
  128.     {
  129.         DIAGS(("WARNING: clnt %d cannot close window %d (not owner)\n",clnt_pid,w->handle));
  130.         pb->intout[0]=0;            /* Invalid window handle, return error */
  131.         return XAC_DONE;
  132.     }
  133.  
  134. #if JOHAN_RECTANGLES
  135.     invalidate_rect_lists(w);
  136. #endif
  137.     v_hide_c(V_handle);
  138.  
  139.     display_windows_below(w);            /* Redisplay any windows below the one we are closing */
  140.  
  141.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  142.  
  143.     if (w==window_list)
  144.     {
  145.          window_list=w->next;
  146.         display_non_topped_window(window_list, NULL);
  147.     }
  148.  
  149.     v_show_c(V_handle,1);
  150.  
  151.     if (w->prev)                        /* Remove the window from the window list */
  152.         w->prev->next=w->next;
  153.     
  154.     if (w->next)
  155.         w->next->prev=w->prev;
  156.     
  157.     w->next=root_window->next;            /* Keep closed windows on the other side of the root window */
  158.     w->prev=root_window;
  159.     if (root_window->next)
  160.         root_window->next->prev=w;
  161.     root_window->next=w;
  162.  
  163.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  164.     
  165.     w->is_open=FALSE;        /* tag window as closed */
  166.     w->window_status=XAWS_CLOSED;
  167.  
  168.     /* New top window - change the cursor to this clients choice */
  169.     graf_mouse(clients[window_list->owner].client_mouse, clients[window_list->owner].client_mouse_form);
  170.     
  171.     pb->intout[0]=1;
  172.     
  173.     return XAC_DONE;
  174. }
  175.  
  176. unsigned long XA_wind_find(short clnt_pid,AESPB *pb)
  177. {
  178.     XA_WINDOW *w;
  179.     
  180.     w=wind_find(pb->intin[0], pb->intin[1]);    /* Is there a window under the mouse? */
  181.  
  182.     if (w==NULL)
  183.     {
  184.         pb->intout[0]=0;
  185.         return XAC_DONE;
  186.     }
  187.  
  188.     pb->intout[0]=w->handle;    /* Found a window, return the handle */
  189.  
  190.     return XAC_DONE;
  191. }
  192.  
  193. void update_vslide(XA_WINDOW *wind)
  194. {
  195. #if JOHAN_RECTANGLES
  196.     XA_RECT_LIST *rl, *drl;
  197. #else
  198.     XA_RECT_LIST *rl=generate_rect_list(wind),*drl;
  199. #endif
  200.     short x,y,pnt[4];
  201.     XA_WIDGET *widg=wind->widgets;
  202.  
  203. #if JOHAN_RECTANGLES
  204.     if (!(rl = wind->rl_full))
  205.         rl = wind->rl_full = generate_rect_list(wind);
  206. #endif
  207.  
  208.     widg+=XAW_VSLIDE;
  209.     
  210.     rp_2_ap(wind, widg, &x, &y);    /* Convert relative coords and window location to absolute screen location */
  211.     pnt[0]=x; pnt[1]=y;
  212.     pnt[2]=x+widg->w; pnt[3]=y+widg->h;
  213.     vsf_color(V_handle,display.dial_colours.bg_col);
  214.     vsf_interior(V_handle,FIS_SOLID);
  215.     
  216.     v_hide_c(V_handle);
  217.     for(drl=rl; drl; drl=drl->next)                /* Walk the rectangle list */
  218.     {
  219.         set_clip(drl->x, drl->y, drl->w, drl->h);
  220.         v_bar(V_handle,pnt);
  221.         display_vslide(wind, widg);
  222.     }
  223.     v_show_c(V_handle,1);
  224. }
  225.  
  226. void update_hslide(XA_WINDOW *wind)
  227. {
  228. #if JOHAN_RECTANGLES
  229.     XA_RECT_LIST *rl, *drl;
  230. #else
  231.     XA_RECT_LIST *rl=generate_rect_list(wind),*drl;
  232. #endif
  233.     short x,y,pnt[4];
  234.     XA_WIDGET *widg=wind->widgets;
  235.     
  236. #if JOHAN_RECTANGLES
  237.     if (!(rl = wind->rl_full))
  238.         rl = wind->rl_full = generate_rect_list(wind);
  239. #endif
  240.     
  241.     widg+=XAW_HSLIDE;
  242.     
  243.     rp_2_ap(wind, widg, &x, &y);    /* Convert relative coords and window location to absolute screen location */
  244.     pnt[0]=x; pnt[1]=y;
  245.     pnt[2]=x+widg->w; pnt[3]=y+widg->h;
  246.     vsf_color(V_handle,display.dial_colours.bg_col);
  247.     vsf_interior(V_handle,FIS_SOLID);
  248.     vsf_color(V_handle,display.dial_colours.bg_col);
  249.     vsf_interior(V_handle,FIS_SOLID);
  250.     
  251.     v_hide_c(V_handle);
  252.     for(drl=rl; drl; drl=drl->next)                /* Walk the rectangle list */
  253.     {
  254.         set_clip(drl->x, drl->y, drl->w, drl->h);
  255.         v_bar(V_handle,pnt);
  256.         display_hslide(wind, widg);
  257.     }
  258.     v_show_c(V_handle,1);
  259. }
  260.  
  261. unsigned long XA_wind_set(short clnt_pid, AESPB *pb)
  262. {
  263.     XA_WINDOW *w,*wl;
  264.     OBJECT *ob;
  265.     GRECT clip,our_win;
  266.     short wind=pb->intin[0],cmd=pb->intin[1];
  267.     unsigned short *l;
  268.     char *t;
  269.     
  270.     w=get_wind_by_handle(wind);
  271.  
  272.     if (w==NULL)
  273.     {
  274.         DIAGS(("WARNING:wind_set:Invalid window handle =%d\n",w));
  275.         pb->intout[0]=0;            /* Invalid window handle, return error */
  276.         return XAC_DONE;
  277.     }
  278.  
  279.     if ((w->owner!=clnt_pid)        /* Clients can only change their own windows */
  280.         &&((w!=root_window)||(cmd!=WF_NEWDESK)))
  281.     {
  282.         DIAGS(("WARNING: clnt %d cannot change window %d (not owner)\n",clnt_pid,w->handle));
  283.         pb->intout[0]=0;            /* Invalid window handle, return error */
  284.         return XAC_DONE;
  285.     }
  286.     
  287.     switch(cmd)
  288.     {
  289.         case WF_HSLIDE:
  290.             if (w->widgets[XAW_HSLIDE].stuff)
  291.             {
  292.                 XA_SLIDER_WIDGET *slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_HSLIDE].stuff);
  293.                 short p=pb->intin[2];
  294.                 
  295.                 if (p<0) p=0;
  296.                 if (p>1000) p=1000;
  297.                 
  298.                 slw->position=p;
  299.                 
  300.                 update_hslide(w);
  301.             }
  302.             break;
  303.         case WF_VSLIDE:
  304.             if (w->widgets[XAW_VSLIDE].stuff)
  305.             {
  306.                 XA_SLIDER_WIDGET *slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_VSLIDE].stuff);
  307.                 short p=pb->intin[2];
  308.                 
  309.                 if (p<0) p=0;
  310.                 if (p>1000) p=1000;
  311.                 
  312.                 slw->position=p;
  313.                 update_vslide(w);
  314.             }
  315.             break;
  316.         case WF_HSLSIZE:
  317.             if (w->widgets[XAW_HSLIDE].stuff)
  318.             {
  319.                 XA_SLIDER_WIDGET *slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_HSLIDE].stuff);
  320.                 short p=pb->intin[2];
  321.                 
  322.                 if (p<0) p=0;
  323.                 if (p>1000) p=1000;
  324.                 
  325.                 slw->length=p;
  326.                 update_hslide(w);
  327.             }
  328.             break;
  329.         case WF_VSLSIZE:
  330.             if (w->widgets[XAW_VSLIDE].stuff)
  331.             {
  332.                 XA_SLIDER_WIDGET *slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_VSLIDE].stuff);
  333.                 short p=pb->intin[2];
  334.                 
  335.                 if (p<0) p=0;
  336.                 if (p>1000) p=1000;
  337.                 
  338.                 slw->length=p;
  339.                 update_vslide(w);
  340.             }
  341.             break;
  342.         case WF_NAME:
  343.             l=(unsigned short*)(pb->intin);
  344.             t=(char*)(l[2]<<16);
  345.             t+=l[3];
  346.             w->widgets[XAW_TITLE].stuff=(void*)t;
  347.  
  348.             v_hide_c(V_handle);
  349.             if (w->is_open)
  350.             {
  351.                 rp_2_ap(w, w->widgets+XAW_TITLE, &clip.g_x, &clip.g_y);
  352.     
  353.                 clip.g_w=w->widgets[XAW_TITLE].w;
  354.                 clip.g_h=w->widgets[XAW_TITLE].h;
  355.  
  356.                 display_non_topped_window(w,&clip);
  357.             }
  358.             v_show_c(V_handle,1);
  359.             break;
  360.         case WF_INFO:
  361.             l=(unsigned short*)(pb->intin);
  362.             t=(char*)(l[2]<<16);
  363.             t+=l[3];
  364.             w->widgets[XAW_INFO].stuff=(void*)t;
  365.  
  366.             v_hide_c(V_handle);
  367.             if ((w->active_widgets&INFO)&&(w->is_open))
  368.             {
  369.                 rp_2_ap(w, w->widgets+XAW_INFO, &clip.g_x, &clip.g_y);
  370.     
  371.                 clip.g_w=w->widgets[XAW_INFO].w;
  372.                 clip.g_h=w->widgets[XAW_INFO].h;
  373.  
  374.                 display_non_topped_window(w,&clip);
  375.             }
  376.             v_show_c(V_handle,1);
  377.             break;
  378.         case WF_CURRXYWH:            /* Move a window */
  379.             w->prev_x=w->x;                /* Save windows previous coords */
  380.             w->prev_y=w->y;
  381.             w->prev_w=w->w;
  382.             w->prev_h=w->h;
  383.  
  384.             our_win.g_x=w->x; our_win.g_y=w->y;
  385.             our_win.g_w=w->w; our_win.g_h=w->h;
  386.             
  387.             w->x=pb->intin[2];            /* Change the window coords */
  388.             w->y=pb->intin[3];
  389.             w->w=pb->intin[4];
  390.             w->h=pb->intin[5];
  391.  
  392.             calc_work_area(w);            /* Recalculate the work area (as well as moving, */
  393.                                         /* it might have changed size). */
  394.             
  395.             v_hide_c(V_handle);
  396.             
  397.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  398.  
  399. #if JOHAN_RECTANGLES
  400.             invalidate_rect_lists(w);
  401.             for(wl=w->next; wl; wl=wl->next)
  402. #else
  403.             for(wl=w; wl; wl=wl->next)
  404. #endif
  405.             {
  406.                 clip.g_x=wl->x; clip.g_y=wl->y;
  407.                 clip.g_w=wl->w; clip.g_h=wl->h;
  408.                 
  409.                 if (rc_intersect(&our_win,&clip))
  410.                 {
  411.                     display_non_topped_window(wl,&clip);
  412.                     send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
  413.                 }
  414.             }
  415.             
  416.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  417.             
  418.             display_non_topped_window(w,NULL);    /* Re-display any revealed windows */
  419.             
  420.             v_show_c(V_handle,1);
  421.             
  422.             send_app_message(clnt_pid, WM_REDRAW, 0, w->handle, w->wx, w->wy, w->ww, w->wh);
  423.  
  424.             break;
  425.         case WF_BOTTOM:                /* Extension, send window to the bottom */
  426.             v_hide_c(V_handle);
  427. #if JOHAN_RECTANGLES
  428.             invalidate_rect_lists(w);    /* Must be done while we have the original */
  429. #endif
  430.             send_wind_to_bottom(w);            /* Send it to the back */
  431.             
  432.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  433.  
  434.             our_win.g_x=w->x; our_win.g_y=w->y;
  435.             our_win.g_w=w->w; our_win.g_h=w->h;
  436.             
  437. #if JOHAN_RECTANGLES
  438.             if (w->prev) 
  439.             {
  440.                 display_non_topped_window(w, NULL);
  441.  
  442.                 for(wl=w->prev; wl->prev; wl=wl->prev)
  443. #else
  444.                 for(wl=w->prev; wl; wl=wl->prev)
  445. #endif
  446.                 {
  447.                     clip.g_x=wl->x; clip.g_y=wl->y;
  448.                     clip.g_w=wl->w; clip.g_h=wl->h;
  449.                 
  450.                     if (rc_intersect(&our_win,&clip))
  451.                     {
  452.                         display_non_topped_window(wl,&clip);    /* Re-display any revealed windows */
  453.                         send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
  454.                     }
  455.                 }
  456. #if JOHAN_RECTANGLES
  457.  
  458.                 display_non_topped_window(wl, NULL);    /* Re-display new top window */
  459.                 clip.g_x=wl->x; clip.g_y=wl->y;
  460.                 clip.g_w=wl->w; clip.g_h=wl->h;
  461.                 if (rc_intersect(&our_win,&clip))
  462.                     send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
  463.             }
  464. #endif
  465.             
  466.             Psemaphore(3,WIN_LIST_SEMAPHORE,0);
  467.  
  468.             v_show_c(V_handle,1);
  469.             break;
  470.         case WF_TOP:                /* Top the window */
  471.             if (w->is_open)
  472.             {
  473.                 pull_wind_to_top(w);
  474.                                 /* New top window - change the cursor to this clients choice */
  475.                 graf_mouse(clients[clnt_pid].client_mouse, clients[clnt_pid].client_mouse_form);
  476.                                 /* Display the previous top window as un-topped */
  477.             
  478.                 v_hide_c(V_handle);
  479.                 Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  480.  
  481. #if JOHAN_RECTANGLES
  482.                 invalidate_rect_lists(w);
  483. #endif
  484.  
  485.                 if ((window_list->next)&&(window_list->next->is_open))
  486.                     display_non_topped_window(window_list->next,NULL);
  487.             
  488.                 Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  489.                 v_show_c(V_handle,1);
  490.  
  491.                 display_non_topped_window(w,NULL);    /* Display the window */
  492.                 send_app_message(clnt_pid, WM_REDRAW, 0, w->handle, w->x, w->y, w->w, w->h);
  493.             }
  494.             
  495.             break;
  496.             
  497.         case WF_NEWDESK:    /* Set a new desktop object tree */
  498.             l=(unsigned short*)pb->intin;
  499.             t=(char*)(l[2]<<16);
  500.             t+=l[3];
  501.             ob=(OBJECT*)t;
  502.             
  503.             if (ob)
  504.             {
  505.                 clients[clnt_pid].desktop=ob;
  506.                 set_desktop(ob);
  507.                 root_window->owner=clnt_pid;
  508.             }else{
  509.                 clients[clnt_pid].desktop=NULL;
  510.                 set_desktop((OBJECT*)ResourceTree(system_resources,DEF_DESKTOP));
  511.             }
  512.             
  513.             v_hide_c(V_handle);
  514.             display_non_topped_window(root_window,NULL);
  515.             v_show_c(V_handle,1);
  516.             
  517.             break;
  518.             
  519.         case WF_AUTOREDRAW:        /* Set an auto-redraw callback function for the window */
  520.             l=(unsigned short*)pb->intin;
  521.             t=(char*)(l[2]<<16);
  522.             t+=l[3];
  523.             w->redraw=(WindowDisplayCallback)t;
  524.             break;
  525.             
  526.         case WF_STOREBACK:        /* Set the window's 'preserve own background' attribute */
  527.             w->background=(void*)malloc(display.planes*((w->w+35)>>2)*(w->h+20));
  528.             w->bgx=-1;
  529.             w->active_widgets|=STORE_BACK|NO_REDRAWS;
  530.             
  531.             break;
  532.         
  533.         case WF_ICONIFY:        /* Iconify a window */
  534.             w->prev_x=w->x;                /* Save windows previous coords */
  535.             w->prev_y=w->y;
  536.             w->prev_w=w->w;
  537.             w->prev_h=w->h;
  538.  
  539.             our_win.g_x=w->x; our_win.g_y=w->y;
  540.             our_win.g_w=w->w; our_win.g_h=w->h;
  541.  
  542.             w->window_status=XAWS_ICONIFIED;
  543.             w->x=pb->intin[2];            /* Change the window coords */
  544.             w->y=pb->intin[3];
  545.             w->w=pb->intin[4];
  546.             w->h=pb->intin[5];
  547.             
  548.             v_hide_c(V_handle);
  549.             
  550.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  551.  
  552. #if JOHAN_RECTANGLES
  553.             invalidate_rect_lists(w);
  554. #endif
  555.             for(wl=w; wl; wl=wl->next)
  556.             {
  557.                 clip.g_x=wl->x; clip.g_y=wl->y;
  558.                 clip.g_w=wl->w; clip.g_h=wl->h;
  559.                 
  560.                 if (rc_intersect(&our_win,&clip))
  561.                 {
  562.                     display_non_topped_window(wl,&clip);
  563.                     send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
  564.                 }
  565.             }
  566.             
  567.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  568.             
  569.             display_non_topped_window(w,NULL);    /* Re-display any revealed windows */
  570.             send_app_message(clnt_pid, WM_REDRAW, 0, w->handle, w->wx, w->wy, w->ww, w->wh);
  571.             
  572.             v_show_c(V_handle,1);
  573.             
  574.             break;
  575.  
  576.         case WF_UNICONIFY:        /* Un-Iconify a window */
  577.  
  578.             our_win.g_x=w->x; our_win.g_y=w->y;
  579.             our_win.g_w=w->w; our_win.g_h=w->h;
  580.  
  581.             w->window_status=XAWS_OPEN;
  582.  
  583.             w->x=w->prev_x;        /* Restore window to previous position */
  584.             w->y=w->prev_y;
  585.             w->w=w->prev_w;
  586.             w->h=w->prev_h;
  587.             
  588.             v_hide_c(V_handle);
  589.             
  590.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  591. #if JOHAN_RECTANGLES
  592.             invalidate_rect_lists(w);
  593. #endif
  594.             for(wl=w; wl; wl=wl->next)
  595.             {
  596.                 clip.g_x=wl->x; clip.g_y=wl->y;
  597.                 clip.g_w=wl->w; clip.g_h=wl->h;
  598.                 
  599.                 if (rc_intersect(&our_win,&clip))
  600.                 {
  601.                     display_non_topped_window(wl,&clip);
  602.                     send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
  603.                 }
  604.             }
  605.             
  606.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  607.             
  608.             display_non_topped_window(w,NULL);    /* Re-display any revealed windows */
  609.             
  610.             v_show_c(V_handle,1);
  611.             
  612.             break;
  613.  
  614.     }
  615.  
  616.     pb->intout[0]=1;
  617.     return XAC_DONE;
  618. }
  619.  
  620. /* AES wind_get() function. */
  621. /* This includes support for most of the AES4 / AES4.1 extensions, */
  622. /* with the exception of WF_BEVENT (all XaAES windows get button events in the */
  623. /* background at the moment). */
  624. unsigned long XA_wind_get(short clnt_pid, AESPB *pb)
  625. {
  626.     XA_WINDOW *w;
  627.     XA_RECT_LIST *rl,*drl;
  628.     XA_SLIDER_WIDGET *slw;
  629.     short wind=pb->intin[0],cmd=pb->intin[1];
  630.     GRECT s,d;
  631.     
  632.     w=get_wind_by_handle(wind);
  633.  
  634.     if (w==NULL)
  635.     {
  636.         DIAGS(("WARNING:wind_get:Invalid window handle =%d\n",wind));
  637.         pb->intout[0]=0;            /* Invalid window handle, return error */
  638.         return XAC_DONE;
  639.     }
  640.  
  641.     pb->intout[0]=1;
  642.  
  643.     switch(cmd)
  644.     {
  645.         case WF_FIRSTXYWH:            /* Generate a rectangle list and return the first entry */
  646. #if JOHAN_RECTANGLES
  647.             if (!w->rl_full)
  648.                 w->rl_full = generate_rect_list(w);    /* Call the internal rectangle list generator. */
  649.  
  650. #else
  651.             for(rl=w->rect_list; rl; )    /* Dispose of any existing rectangle list */
  652.             {
  653.                 drl=rl;
  654.                 rl=rl->next;
  655.                 free(rl);
  656.             }
  657.             w->rect_list=NULL;
  658.             
  659.             rl=generate_rect_list(w);    /* Call the internal rectangle list generator. */
  660.             
  661.             for(drl=rl; rl; drl=rl)        /* Fix the rectangle list to clip to the work area only */
  662.             {
  663.                 s.g_x=rl->x;
  664.                 s.g_y=rl->y;
  665.                 s.g_w=rl->w;
  666.                 s.g_h=rl->h;
  667.                 d.g_x=w->wx;
  668.                 d.g_y=w->wy;
  669.                 d.g_w=w->ww;
  670.                 d.g_h=w->wh;
  671.                 rl=rl->next;
  672.                 if (rc_intersect(&s, &d))    /* Optimise the rectangle list to only do bit's  */
  673.                 {                            /* that intersect the work area */
  674.                     drl->x=d.g_x;
  675.                     drl->y=d.g_y;
  676.                     drl->w=d.g_w+1;
  677.                     drl->h=d.g_h+1;
  678.                     drl->next=w->rect_list;
  679.                     w->rect_list=drl;
  680.                 }else{
  681.                     free(drl);
  682.                 }
  683.             }
  684. #endif
  685.  
  686. #if JOHAN_RECTANGLES
  687.             if (!w->rl_work)
  688.                 w->rl_work = create_work_list(w);    /* Call the internal full->work clip routine. */
  689.  
  690.             if (rl = w->rl_work) {            /* Did we get any rectangles? */
  691.                 w->rl_work_cur = rl->next;
  692. #else
  693.             if (w->rect_list)            /* Did we get any rectangles? */
  694.             {
  695.                 rl=w->rect_list;
  696.                 w->rect_list=rl->next;
  697. #endif
  698.                 pb->intout[1]=rl->x;    /* Return the first rectangle coords */
  699.                 pb->intout[2]=rl->y;
  700.                 pb->intout[3]=rl->w;
  701.                 pb->intout[4]=rl->h;
  702. #if JOHAN_RECTANGLES
  703. #else
  704.                 free(rl);                /* Dispose the first entry in the rectangle list */
  705. #endif
  706.             }else{
  707.                 pb->intout[1]=w->wx;    /* Totally obscured window, return w & h as 0 */
  708.                 pb->intout[2]=w->wy;
  709.                 pb->intout[3]=0;
  710.                 pb->intout[4]=0;
  711. #if JOHAN_RECTANGLES
  712. #else
  713.                 w->rect_list=NULL;        /* Window has no rectangle list */
  714. #endif
  715.             }
  716.             break;
  717.         case WF_NEXTXYWH:            /* Get next entry from a rectangle list */
  718. #if JOHAN_RECTANGLES
  719.             if (rl = w->rl_work_cur) {    /* Are there any rectangles left in the list? */
  720.                 w->rl_work_cur = rl->next;
  721. #else
  722.             if (w->rect_list!=NULL)        /* Are there any rectangles left in the list ? */
  723.             {
  724.                 rl=w->rect_list;
  725.                 w->rect_list=rl->next;
  726. #endif
  727.                 pb->intout[1]=rl->x;    /* Return the next rectangle coords */
  728.                 pb->intout[2]=rl->y;
  729.                 pb->intout[3]=rl->w;
  730.                 pb->intout[4]=rl->h;
  731. #if JOHAN_RECTANGLES
  732. #else
  733.                 free(rl);                /* Dispose the entry in the rectangle list */
  734. #endif
  735.             }else{
  736.                 pb->intout[1]=0;        /* No rectangles left - return all zero */
  737.                 pb->intout[2]=0;
  738.                 pb->intout[3]=0;
  739.                 pb->intout[4]=0;
  740.             }
  741.             break;
  742.         case WF_CURRXYWH:            /* Get the current coords of the window */
  743.             pb->intout[1]=w->x;        /* Return the window coords */
  744.             pb->intout[2]=w->y;
  745.             pb->intout[3]=w->w;
  746.             pb->intout[4]=w->h;
  747.             break;
  748.         case WF_WORKXYWH:            /* Get the current coords of the window's user work area */
  749.             pb->intout[1]=w->wx+2;    
  750.             pb->intout[2]=w->wy+2;
  751.             pb->intout[3]=w->ww-4;
  752.             pb->intout[4]=w->wh-4;
  753.             break;
  754.         case WF_PREVXYWH:            /* Get previous window position */
  755.             pb->intout[1]=w->prev_x;
  756.             pb->intout[2]=w->prev_y;
  757.             pb->intout[3]=w->prev_w;
  758.             pb->intout[4]=w->prev_h;
  759.             break;            
  760.         case WF_FULLXYWH:            /* Get maximum window dimensions */
  761.             pb->intout[1]=root_window->x; 
  762.             pb->intout[2]=root_window->wy;    /* ensure the windows don't overlay the menu bar */
  763.             pb->intout[3]=root_window->w;
  764.             pb->intout[4]=root_window->h-root_window->wy;
  765.             break;
  766.         case WF_BOTTOM:                /* Extension, gets the bottom window */
  767.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  768.             for(w=window_list; w->next; w=w->next);
  769.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  770.             pb->intout[1]=w->handle;    /* Return the window handle of the bottom window */
  771.             pb->intout[2]=w->owner;        /* Return the owner of the bottom window */
  772.             break;
  773.         case WF_TOP:
  774.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  775.             w=window_list;
  776.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  777.             if (w)
  778.             {
  779.                 pb->intout[1]=w->handle;    /* Return the window handle */
  780.                 pb->intout[2]=w->owner;        /* AES4 specifies that you return the AESid of the owner here as well */
  781.                 if (w->next)                /* Is there a window below?  */
  782.                 {                            /* if there is, then AES4 says return it's handle here */
  783.                     pb->intout[3]=w->next->handle;
  784.                     pb->intout[4]=w->next->owner;    /* XaAES extentin - return the AESid of the app that owns the window below */
  785.                 }else{
  786.                     pb->intout[3]=0;
  787.                     pb->intout[4]=0;
  788.                 }
  789.             }else{
  790.                 pb->intout[1]=0;    /* No windows open - return an error */
  791.                 pb->intout[0]=0;
  792.                 return XAC_DONE;
  793.             }
  794.             break;
  795.         case WF_OWNER:                /* AES4 compatible stuff */
  796.             pb->intout[1]=w->owner;        /* The window owners AESid (==app_id) */
  797.             pb->intout[2]=w->is_open;    /* Is the window open? */
  798.             if (w->prev)                /* If there is a window above, return it's handle */
  799.             {
  800.                 pb->intout[3]=w->prev->handle;
  801.             }else{
  802.                 pb->intout[3]=0;
  803.             }
  804.             
  805.             if (w->next)                /* If there is a window below, return it's handle */
  806.             {
  807.                 pb->intout[4]=w->next->handle;
  808.             }else{
  809.                 pb->intout[4]=0;
  810.             }
  811.             break;
  812.         case WF_VSLIDE:
  813.             if (w->active_widgets&VSLIDE)
  814.             {
  815.                 slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_VSLIDE].stuff);
  816.                 pb->intout[1]=slw->position;
  817.             }else{
  818.                 pb->intout[0]=pb->intout[1]=0;
  819.                 return XAC_DONE;
  820.             }
  821.             break;
  822.         case WF_HSLIDE:
  823.             if (w->active_widgets&HSLIDE)
  824.             {
  825.                 slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_HSLIDE].stuff);
  826.                 pb->intout[1]=slw->position;
  827.             }else{
  828.                 pb->intout[0]=pb->intout[1]=0;
  829.                 return XAC_DONE;
  830.             }
  831.             break;
  832.         case WF_HSLSIZE:
  833.             if (w->active_widgets&HSLIDE)
  834.             {
  835.                 slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_HSLIDE].stuff);
  836.                 pb->intout[1]=slw->length;
  837.             }else{
  838.                 pb->intout[0]=pb->intout[1]=0;
  839.                 return XAC_DONE;
  840.             }
  841.             break;
  842.         case WF_VSLSIZE:
  843.             if (w->active_widgets&VSLIDE)
  844.             {
  845.                 slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_VSLIDE].stuff);
  846.                 pb->intout[1]=slw->length;
  847.             }else{
  848.                 pb->intout[0]=pb->intout[1]=0;
  849.                 return XAC_DONE;
  850.             }
  851.             break;
  852.         case WF_NEWDESK:
  853.             Psemaphore(2,ROOT_SEMAPHORE,-1L);
  854.             pb->intout[1]=((unsigned long)desktop&0xffff0000L)>>16;
  855.             pb->intout[2]=(unsigned long)desktop&0x0000ffffL;
  856.             Psemaphore(3,ROOT_SEMAPHORE,0L);
  857.             break;
  858.         
  859.         case WF_ICONIFY:
  860.             if(w->window_status==XAWS_ICONIFIED)
  861.             {
  862.                 pb->intout[1]=1;
  863.                 pb->intout[2]=iconify_w;
  864.                 pb->intout[3]=iconify_h;
  865.             }else{
  866.                 pb->intout[1]=0;
  867.             }
  868.             break;
  869.  
  870.         case WF_UNICONIFY:
  871.             pb->intout[1]=w->prev_x;
  872.             pb->intout[2]=w->prev_y;
  873.             pb->intout[3]=w->prev_w;
  874.             pb->intout[4]=w->prev_h;
  875.             break;
  876.         
  877.     }
  878.     
  879.     return XAC_DONE;
  880. }
  881.  
  882. short update_lock=FALSE;
  883. short mouse_lock=FALSE;
  884. short update_cnt=0;
  885. short mouse_cnt=0;
  886.  
  887. #define    EACCESS    36        /* access denied */
  888.  
  889. /* Wind_update handling */
  890. /* This handles locking for the update and mctrl flags. */
  891. /* !!!!New version - uses semphores to locking... */
  892. unsigned long XA_wind_update(short clnt_pid, AESPB *pb)
  893. {
  894.     short op=pb->intin[0];
  895.     long timeout=(op&0x100)?0L:-1L;    /* test for check-and-set mode */
  896.  
  897.     pb->intout[0]=1;
  898.  
  899.     switch(op)
  900.     {
  901.         case BEG_UPDATE:    /* Grab the update lock */
  902.         case BEG_UPDATE|0x100:
  903.             if (update_lock==clnt_pid)   /* Already owning it? */
  904.             {
  905.                 update_cnt++ ;
  906.                 break ;
  907.             }
  908.             if ( Psemaphore(2,UPDATE_LOCK,timeout)==-EACCESS )
  909.             {
  910.                 pb->intout[0]=0;    /* screen locked by different process */
  911.                 break ;
  912.             }
  913.             update_lock=clnt_pid;
  914.             update_cnt=1 ;
  915.             break;
  916.         case END_UPDATE:
  917.             if ((update_lock==clnt_pid)&&(--update_cnt==0))
  918.             {
  919.                 update_lock=FALSE;
  920.                 Psemaphore(3,UPDATE_LOCK,0);
  921.             }
  922.             break;
  923.         case BEG_MCTRL:        /* Grab the mouse lock */
  924.         case BEG_MCTRL|0x100:
  925.             if (mouse_lock==clnt_pid)   /* Already owning it? */
  926.             {
  927.                 mouse_cnt++ ;
  928.                 break ;
  929.             }
  930.             if ( Psemaphore(2,MOUSE_LOCK,timeout)==-EACCESS )
  931.             {
  932.                 pb->intout[0]=0;    /* mouse locked by different process */
  933.                 break ;
  934.             }
  935.             mouse_lock=clnt_pid;
  936.             mouse_cnt=1 ;
  937.             break;
  938.         case END_MCTRL:
  939.             if ((mouse_lock==clnt_pid)&&(--mouse_cnt==0))
  940.             {
  941.                 mouse_lock=FALSE;
  942.                 Psemaphore(3,MOUSE_LOCK,0);
  943.             }
  944.             break;
  945.     }
  946.     return XAC_DONE;
  947. }
  948.  
  949. unsigned long XA_wind_delete(short clnt_pid, AESPB *pb)
  950. {
  951.     XA_WINDOW *w=get_wind_by_handle(pb->intin[0]);
  952.  
  953.     if (w)
  954.     {
  955.         delete_window(w);
  956.     }
  957.     
  958.     pb->intout[0]=1;
  959.     
  960.     return XAC_DONE;
  961. }
  962.  
  963. /* Go through and check that all windows belonging to this client are */
  964. /* closed and deleted  */
  965. unsigned long XA_wind_new(short clnt_pid, AESPB *pb)
  966. {
  967.     XA_WINDOW *wl,*dwl;
  968.  
  969.     for(wl=window_list; wl;)
  970.     {
  971.         if ((wl->owner==clnt_pid)&&(wl!=root_window))
  972.         {
  973.             dwl=wl;
  974.  
  975.             v_hide_c(V_handle);
  976.             display_windows_below(wl);                /* Redisplay any windows below the one we are closing */
  977.             v_show_c(V_handle, 1);
  978.  
  979.             wl=wl->next;
  980.             
  981.             if (window_list==dwl)                    /* Actually delete the window */
  982.                 window_list=dwl->next;
  983.  
  984.             if (dwl->prev) dwl->prev->next=dwl->next;
  985.             if (dwl->next) dwl->next->prev=dwl->prev;
  986.  
  987.             free(dwl);
  988.         }else{
  989.             wl=wl->next;
  990.         }
  991.     }
  992.     
  993.     return XAC_DONE;
  994. }
  995.  
  996. /*
  997.     wind_calc
  998. */
  999. unsigned long XA_wind_calc(short clnt_pid, AESPB *pb)
  1000. {
  1001.     XA_WINDOW *w_temp;
  1002.     short request=pb->intin[0];
  1003.     
  1004. /* Create a temporary window with the required widgets */
  1005.     w_temp=create_window(clnt_pid, pb->intin[1], pb->intin[2], pb->intin[3], pb->intin[4], pb->intin[5]);
  1006.  
  1007.     switch(request)
  1008.     {
  1009.         case WC_BORDER:                    /* We have to work out the border size ourselves here */
  1010.             pb->intout[1]=2*w_temp->x - w_temp->wx;    /*if you want to prove the maths here, draw two boxes one inside */
  1011.             pb->intout[2]=2*w_temp->y - w_temp->wy;    /* the other, then sit and think about it for a while.... */
  1012.             pb->intout[3]=2*w_temp->w - w_temp->ww +1;
  1013.             pb->intout[4]=2*w_temp->h - w_temp->wh +1;
  1014.             break;
  1015.         case WC_WORK:                    /* Work area was calculated when the window was created */
  1016.             pb->intout[1]=w_temp->wx;
  1017.             pb->intout[2]=w_temp->wy;
  1018.             pb->intout[3]=w_temp->ww+1;
  1019.             pb->intout[4]=w_temp->wh+1;
  1020.             break;
  1021.     }
  1022.  
  1023.     delete_window(w_temp);        /* Dispose of the temporary window we created */
  1024.  
  1025.     pb->intout[0]=1;
  1026.     
  1027.     return XAC_DONE;
  1028. }
  1029.